package com.hk.core.web.filter;

import com.hk.commons.util.StringEscapeHandler;
import com.hk.core.web.RepeatReadHttpServletRequestWrapper;
import com.hk.core.web.XssHttpServletRequestWrapper;
import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpFilter;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.RequiredArgsConstructor;
import org.springframework.http.converter.*;
import org.springframework.http.converter.support.AllEncompassingFormHttpMessageConverter;
import org.springframework.web.servlet.function.RequestPredicate;
import org.springframework.web.servlet.function.ServerRequest;

import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.List;

/**
 * XssFilter
 *
 * @author kevin
 * @date 2018-06-07 17:18
 * *
 */
@RequiredArgsConstructor
public class XssFilter extends HttpFilter {

    public static final String XSS_REQUEST_PREDICATE_BEAN_NAME = "xssRequestPredicate";

    private final RequestPredicate requestPredicate;

    private final StringEscapeHandler stringEscapeHandler;

    private static final List<HttpMessageConverter<?>> httpMessageConverters = List.of(new ByteArrayHttpMessageConverter(),
            new StringHttpMessageConverter(StandardCharsets.UTF_8),
            new ResourceHttpMessageConverter(),
            new ResourceRegionHttpMessageConverter(),
            new AllEncompassingFormHttpMessageConverter());

    @Override
    protected void doFilter(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws IOException, ServletException {
        var wrapper = requestPredicate.test(ServerRequest.create(request, httpMessageConverters)) ?
                new XssHttpServletRequestWrapper(stringEscapeHandler, request) : new RepeatReadHttpServletRequestWrapper(request);
        chain.doFilter(wrapper, response);
    }
}
